unit Pedestrian;

interface

uses Classes, Math, Mathematic, Vector, CoordinateSystem,
 {Behavior} Obstacle, Path, Color, GL, GLu, Dialogs;

const
  CONST_WIDTH = 0.5;

type
  TPedestrianEditor = class;

  TPedestriansList = class(TList)
  private
  public
    constructor Create;
    constructor CreateCopy(paPedestriansList: TPedestriansList);
    destructor Destroy;override;
    procedure Update(paDeltaTime: TFloat);
    procedure Draw;
  end;

  TPedestrianEditor = class
  private
    aPosition: TVector;
    aDestination: TVector;
    aVelocity: TVector;
    aLocalSpace: TCoordinateSystem;
    aPedestriansList: TPedestriansList;
    aObstaclesList: TObstaclesList;
    aPath: TPath;
    aPathCounter: Integer;
    aPathReverse: Boolean;
    aMaxSpeed: TFloat;
    aAcceleration: TFloat;
    aWidth: TFloat;
    aColor: TColor;
    aStopped: Boolean;
    aType: integer;
  public
    constructor Create;
    constructor CreateCopy(paPedestrian: TPedestrianEditor);
    destructor Destroy;override;
    procedure Update(paDeltaTime: TFloat);
    function IsAhead(paTarget: TVector; paCosinus: TFloat): Boolean;
    procedure Stop;
    procedure Resume;
    procedure Draw(paTyp: integer);
    property Position: TVector read aPosition write aPosition;
    property Destination: TVector read aDestination write aDestination;
    property Velocity: TVector read aVelocity;
    property LocalSpace: TCoordinateSystem read aLocalSpace write aLocalSpace;
    property PedestriansList: TPedestriansList read aPedestriansList write aPedestriansList;
    property ObstaclesList: TObstaclesList read aObstaclesList write aObstaclesList;
    property MaxSpeed: TFloat read aMaxSpeed write aMaxSpeed;
    property Acceleration: TFloat read aAcceleration write aAcceleration;
    property Width: TFloat read aWidth write aWidth;
    property Color: TColor read aColor write aColor;
    property Stopped: Boolean read aStopped;
    property Path: TPath read aPath write aPath;
    property PathCounter: Integer read aPathCounter write aPathCounter;
    property PathReverse: Boolean read aPathReverse write aPathReverse;
    property Typ: integer read aType write aType;
  end;

implementation

uses SysUtils, oSimulation;

constructor TPedestriansList.Create;
begin
    inherited Create;
end;

constructor TPedestriansList.CreateCopy(paPedestriansList: TPedestriansList);
begin
    inherited Create;
end;

destructor TPedestriansList.Destroy;
begin
    inherited Destroy;
end;

procedure TPedestriansList.Update(paDeltaTime: TFloat);
var I: Integer;
begin
    for I := 0 to Count - 1 do begin
        TPedestrianEditor(Items[I]).Update(paDeltaTime);
    end;
end;

procedure TPedestriansList.Draw;
var I: Integer;
begin
    for I := 0 to Count - 1  do begin
        TPedestrianEditor(Items[I]).Draw(TPedestrianEditor(Items[i]).Typ);
    end;
   // if Count > 0 then showmessage('vykreslene');


end;

constructor TPedestrianEditor.Create;
begin
    inherited Create;
    aPosition := TVector.Create(0.0, 0.0, 0.0);
    aDestination := TVector.Create(0.0, 0.0, 0.0);
    aVelocity := TVector.Create(1.0, 0.0, 0.0);
    aLocalSpace := TCoordinateSystem.Create;
    aLocalSpace.Setup(aPosition, aVelocity);
    aPedestriansList := nil;
    aObstaclesList := nil;
    aPath := nil;
    aPathCounter := -1;
    aPathReverse := false;
    aMaxSpeed := 1.775;
    aAcceleration := 1.0;
    aWidth := CONST_WIDTH;
    aColor := TColor.Create(0.0, 0.0, 0.0, 0.0); // cierny
end;

constructor TPedestrianEditor.CreateCopy(paPedestrian: TPedestrianEditor);
begin
    inherited Create;
    aPosition := TVector.CreateCopy(paPedestrian.aPosition);
    aDestination := TVector.CreateCopy(paPedestrian.aDestination);
    aVelocity := TVector.CreateCopy(paPedestrian.aVelocity);
    aLocalSpace := TCoordinateSystem.CreateCopy(paPedestrian.aLocalSpace);
    aPedestriansList := TPedestriansList.CreateCopy(paPedestrian.aPedestriansList);
    aObstaclesList := TObstaclesList.CreateCopy(paPedestrian.aObstaclesList);
    aPath := TPath.CreateCopy(paPedestrian.Path);
    aPathCounter := paPedestrian.aPathCounter;
    aPathReverse := paPedestrian.PathReverse;
    aMaxSpeed := paPedestrian.aMaxSpeed;
    aWidth := paPedestrian.aWidth;
    aWidth := CONST_WIDTH;
    aColor := TColor.CreateCopy(paPedestrian.aColor);
end;

destructor TPedestrianEditor.Destroy;
begin
    aPosition.Free;
    aDestination.Free;
    aVelocity.Free;
    aLocalSpace.Free;
    aColor.Free;
    if aPath <> nil then aPath.Free;
    inherited Destroy;
end;

procedure TPedestrianEditor.Update(paDeltaTime: TFloat);
var TotalVelocity: TVector;
begin
    if (paDeltaTime <> 0.0) then begin
        if not aStopped then begin
            aVelocity.AddSelf(TotalVelocity);
            aVelocity.TruncateSelf(aMaxSpeed * aAcceleration);
            aVelocity.MultiplySelf(paDeltaTime);
            aPosition.AddSelf(aVelocity);
            if aVelocity.Length <> 0 then aLocalSpace.Setup(aPosition, aVelocity);
        end;
        TotalVelocity.Free;
    end;
end;

function TPedestrianEditor.IsAhead(paTarget: TVector; paCosinus: TFloat): Boolean;
var TargetDirection: TVector;
    Cosinus: TFloat;
    LocalPosition: TVector;
begin
{
    TargetDirection := paTarget.Subtract(aPosition);
    TargetDirection.NormalizeSelf;
    Cosinus := aLocalSpace.Forward.DotProduct(TargetDirection);
    TargetDirection.Free;
    Result := Cosinus > paCosinus;
}
    LocalPosition := aLocalSpace.LocalizePosition(paTarget);
    Result := LocalPosition.X > 0;
    LocalPosition.Free;
end;


procedure TPedestrianEditor.Stop;
begin
    aStopped := true;
end;

procedure TPedestrianEditor.Resume;
begin
    aStopped := false;
end;

procedure TPedestrianEditor.Draw(paTyp: integer);
var Quad: PGLUquadric;
    VelocityVector: TVector;
begin
    Quad := gluNewQuadric;
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix;
    glTranslated(aPosition.X, aPosition.Y, aPosition.Z);
    glColor4d(0.0, 0.0, 0.0, 0.0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //gluDisk(Quad, aWidth / 2.0, aWidth / 2.0, 64, 1);
//    aWidth := CONST_WIDTH;
 //   glColor4dv(PGLdouble(aColor.DataPointer));
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    //gluDisk(Quad, 0.0, aWidth / 2.0, 64, 1);
    if paTyp = atSS then
      glColor4d(1.0, 0.0, 0.0, 0.0)
    else
      glColor4d(0.0, 1.0, 1.0, 0.0);
    gluDisk(Quad, 0.0, aWidth, 8, 1);
    glColor4d(0.0, 0.0, 0.0, 0.0);
    gluDisk(Quad, aWidth, aWidth*1.1, 8, 1); //konstanty
    gluDeleteQuadric(Quad);
    glPopMatrix;
    if Debug then begin
        VelocityVector := TVector.CreateCopy(aVelocity).ScaleSelf(aMaxSpeed).AddSelf(aPosition);
        glBegin(GL_LINES);
            glVertex3dv(PGLdouble(aPosition.DataPointer));
            glVertex3dv(PGLdouble(VelocityVector.DataPointer));
        glEnd;
        VelocityVector.Free;
    end;
end;

end.
